home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
uemlsrc.arc
/
display.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-08-24
|
34KB
|
991 lines
/*
* The functions in this file
* handle redisplay. There are two halves,
* the ones that update the virtual display
* screen, and the ones that make the physical
* display screen the same as the virtual
* display screen. These functions use hints
* that are left in the windows by the
* commands.
*/
#include <stdio.h>
#include <osbind.h>
#include "ed.h"
#define WFDEBUG 0 /* Window flag debug. */
#define BELL 0x07
typedef struct VIDEO {
short v_flag; /* Flags */
char v_text[]; /* Screen data. */
} VIDEO;
#define VFCHG 0x0001 /* Changed. */
#define VFEXT 0x0002 /* extended (beyond column 80) */
#define VFREV 0x0004 /* reverse ? */
#define VFREQ 0x0008
int sgarbf = TRUE; /* TRUE if screen is garbage */
int mpresf = FALSE; /* TRUE if message in last line */
int vtrow = 0; /* Row location of SW cursor */
int vtcol = 0; /* Column location of SW cursor */
int ttrow = HUGE; /* Row location of HW cursor */
int ttcol = HUGE; /* Column location of HW cursor */
int lbound = 0; /* leftmost column of current ln*/
char mlbuf[256]; /* modeline buffer */
VIDEO **vscreen; /* Virtual screen. */
VIDEO **pscreen; /* Physical screen. */
/*
* Initialize the data structures used
* by the display code. The edge vectors used
* to access the screens are set up. The operating
* system's terminal I/O channel is set up. All the
* other things get initialized at compile time.
* The original window has "WFCHG" set, so that it
* will get completely redrawn on the first
* call to "update".
*/
vtinit()
{
register int i;
register VIDEO *vp;
#if ST
/* save current colors for later */
savecolor();
#endif
(*term.t_open)();
vscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
if (vscreen == NULL)
abort();
pscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
if (pscreen == NULL)
abort();
for (i=0; i<term.t_nrow; ++i) {
vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
if (vp == NULL)
abort();
vp->v_flag = 0;
vscreen[i] = vp;
vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
if (vp == NULL)
abort();
vp->v_flag = 0;
pscreen[i] = vp;
}
}
/*
* Clean up the virtual terminal
* system, in anticipation for a return to the
* operating system. Move down to the last line and
* clear it out (the next system prompt will be
* written in the line). Shut down the channel
* to the terminal.
*/
vttidy()
{
mlerase();
movecursor(term.t_nrow, 0);
(*term.t_eeol)();
(*term.t_close)();
}
/*
* Set the virtual cursor to
* the specified row and column on the
* virtual screen. There is no checking for
* nonsense values; this might be a good
* idea during the early stages.
*/
vtmove(row, col)
register int row, col;
{
vtrow = row;
vtcol = col;
}
/*
* Write a character to the
* virtual screen. The virtual row and
* column are updated. If the line is too
* long put a "$" in the last column.
* This routine only puts printing characters
* into the virtual terminal buffers.
* Only column overflow is checked.
*/
vtputc(c)
register int c;
{
register VIDEO *vp;
vp = vscreen[vtrow];
if (vtcol >= term.t_ncol) {
vtcol = (vtcol + 0x07) & ~0x07;
vp->v_text[term.t_ncol-1] = '$';
}
else if (c == '\t') {
do {
vtputc(' ');
} while ((vtcol&0x07) != 0);
} else if (c<0x20 || c==0x7F) {
vtputc('^');
vtputc(c ^ 0x40);
} else
vp->v_text[vtcol++] = c;
}
/*
* put a character to the virtual screen in an extended line. If we are
* not yet on left edge, don't print it yet. check for overflow on
* the right margin.
*/
vtpute(c)
register int c;
{
register VIDEO *vp;
vp = vscreen[vtrow];
if (vtcol >= term.t_ncol) {
vtcol = (vtcol + 0x07) & ~0x07;
vp->v_text[term.t_ncol - 1] = '$';
}
else if (c == '\t') {
do {
vtpute(' ');
} while (((vtcol + lbound)&0x07) != 0);
}
else if (c < 0x20 || c == 0x7F) {
vtpute('^');
vtpute(c ^ 0x40);
}
else {
if (vtcol >= 0)
vp->v_text[vtcol] = c;
++vtcol;
}
}
/*
* Erase from the end of the
* software cursor to the end of the
* line on which the software cursor is
* located.
*/
vteeol()
{
register VIDEO *vp;
vp = vscreen[vtrow];
while (vtcol < term.t_ncol)
vp->v_text[vtcol++] = ' ';
}
/*
* Make sure that the display is
* right. This is a three part process. First,
* scan through all of the windows looking for dirty
* ones. Check the framing, and refresh the screen.
* Second, make sure that "currow" and "curcol" are
* correct for the current window. Third, make the
* virtual and physical screens the same.
*/
update()
{
register LINE *lp;
register WINDOW *wp;
register VIDEO *vp1;
register VIDEO *vp2;
register int i;
register int j;
register int c;
#if ST
Bconout(2,0x1b); /* hide cursor */
Bconout(2,'f');
#endif
for (i = 0; i < term.t_nrow; ++i)
vscreen[i]->v_flag &= ~VFREQ;
#if ST
wp = wheadp;
while (wp != NULL) {
vscreen[wp->w_toprow+wp->w_ntrows]->v_flag |= VFREQ;
wp = wp->w_wndp;
}
#endif
wp = wheadp;
while (wp != NULL) {
/* Look at any window with update flags set on. */
if (wp->w_flag != 0) {
/* If not force reframe, check the framing. */
if ((wp->w_flag&WFFORCE) == 0) {
lp = wp->w_linep;
for (i=0; i<wp->w_ntrows; ++i) {
if (lp == wp->w_dotp)
goto out;
if (lp == wp->w_bufp->b_linep)
break;
lp = lforw(lp);
}
}
/* Not acceptable, better compute a new value */
/* for the line at the top of the window. Then */
/* set the "WFHARD" flag to force full redraw. */
i = wp->w_force;
if (i > 0) {
--i;
if (i >= wp->w_ntrows)
i = wp->w_ntrows-1;
} else if (i < 0) {
i += wp->w_ntrows;
if (i < 0)
i = 0;
} else
i = wp->w_ntrows/2;
lp = wp->w_dotp;
while (i!=0 && lback(lp)!=wp->w_bufp->b_linep) {
--i;
lp = lback(lp);
}
wp->w_linep = lp;
wp->w_flag |= WFHARD; /* Force full. */